﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using IFWiki.Utils;

namespace IFWiki.Models
{
    public partial class Game : IRevisable
    {
        /// <summary>
        /// The name of the game. Can contain spaces and other characters        
        /// </summary>
        /// <value>The name.</value>
        public string Name { get; set; }

        /// <summary>
        /// Markdown describing the game -- will appear in the 'introduction' 
        /// page of the game, and may be pushed into other lists of games.
        /// </summary>
        public string AboutGame { get; set; }

        /// <summary>
        /// A chunk of JSON that describes the default player.
        /// A player will have:
        ///     'vitals'
        ///     'items' (things that are collectable, tradeable, potentially weapons)
        /// A player may also have:
        ///     'skills'
        /// </summary>
        public string StartingPlayerJson { get; set; }

        /// <summary>
        /// The name of place where the game begins.
        /// A game is composed of many places. This is the first one.
        /// </summary>
        public string StartingGamePlaceName { get; set; }

        /// <summary>
        /// Any style sheet information that is used on every page of the game
        /// (including the intro screen of the game)
        /// </summary>
        public string GameStyle { get; set; }

        /// <summary>
        /// Every time you enter a new place, this piece of Javascript is run
        /// (before the place runs its own starting script)
        /// For example, in a typical game you might make the player 1 hour 
        /// older every time they move from one place to the next
        /// </summary>
        public string OnPlaceEnterJS { get; set; }

        /// <summary>
        /// Tags about this game. For use in tag clouds/categories etc.
        /// Not yet implemented.
        /// </summary>
        public string Tags { get; set; }


        public string Reason { get; set; }
        public DateTime RevisedAt { get; set; }
        public string RevisedBy { get; set; }
        public bool IsDiscussion { get { return false; } }

        public string InnerType { get { return "Game"; } }
    }

    public partial class Game
    {
        public Game()
        {
            //parameterless, for serialization
        }
        public Game(string name)
        {
            this.Name = name;

            if (name != null)
            {

                var savedGame = (Game)Persister.Load(this.Name, this.GetType()) ?? Defaults.GetGame(name);
                this.Name = savedGame.Name;
                this.AboutGame = savedGame.AboutGame;
                this.GameStyle = savedGame.GameStyle;
                this.OnPlaceEnterJS = savedGame.OnPlaceEnterJS;
                this.StartingGamePlaceName = savedGame.StartingGamePlaceName;
                this.StartingPlayerJson = savedGame.StartingPlayerJson;
                this.Tags = savedGame.Tags;
            }
        }

        public void Save(string reason, string revisedBy)
        {
            this.Reason = reason;
            this.RevisedAt = DateTime.Now;
            this.RevisedBy = revisedBy;
            Debug.Assert(!string.IsNullOrEmpty(this.Name));
            Persister.Save(this.Name, this, this.RevisedAt );
        }

        public List<IRevisable> LoadRevisions()
        {
            var revisions = new List<IRevisable>();
            revisions = Persister.LoadList<IRevisable>(this.Name, typeof(Game)); // ?? Defaults.GetArticle(name);
            return revisions;
        }

        internal static Game Revert(string name, DateTime revisedAt, string revertedBy)
        {
            var game = LoadRevision(name, revisedAt);
            game.Save("revert from " + revisedAt.ToString(), revertedBy);
            return game;
        }

        public static Game LoadRevision(string name, DateTime revisedAt)
        {
            return Persister.LoadRevision<Game>(name, revisedAt, typeof(Game));
        }
    }
}
